package com.ruoyi.ade.llm.agent;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baidubce.qianfan.Qianfan;
import com.baidubce.qianfan.QianfanV2;
import com.baidubce.qianfan.model.chat.v2.Message;
import com.baidubce.qianfan.model.chat.v2.request.RequestV2;
import com.baidubce.qianfan.model.chat.v2.response.ResponseV2;
import com.ruoyi.ade.llm.exception.QianfanException;
import com.ruoyi.ade.llm.model.ChatRequest;
import com.ruoyi.ade.llm.model.ChatResponse;
import com.ruoyi.ade.llm.model.RerankRequest;
import com.ruoyi.ade.llm.model.RerankResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class QianfanAgent extends LLMAgent{

    public static final String model_ernie35_8k = "ernie-3.5-8k";
    public static final String model_ernie4_8k = "ernie-4.0-8k";
    public static final String model_deepseek_v3 = "deepseek-v3";
    public static final String model_deepseek_r1 = "deepseek-r1";



    private final String ACCESS_KEY = "ALTAK9so5IblfsvwYKkOg6OB3A";

    //apikey="bce-v3/ALTAK-ejd505PGk8zJZ9XBl8ula/b08e7a873699b5b5d2414b049b51c0a6acff9727"
    //deepseek: sk-4f673560bdcd4e4da7d7140644ad2e77
    private final String SECRET_KEY = "001d1fe8f7344824a2ed8a0bf2f1f118";
    private final String API_KEY = "bce-v3/ALTAK-ejd505PGk8zJZ9XBl8ula/b08e7a873699b5b5d2414b049b51c0a6acff9727";

    private QianfanV2 qianfan;

    private QianfanAgent() {
        qianfan = new Qianfan(ACCESS_KEY,SECRET_KEY).v2();
    }


    private static class SingletonHelper{
        private static QianfanAgent INSTANCE = new QianfanAgent();
    }
    public static QianfanAgent getInstance(){
        return SingletonHelper.INSTANCE;
    }


    /**
     *  大模型调用
     * @param request
     * @return
     */
    public ChatResponse chat(ChatRequest request){
        ResponseV2 response =  null;
        try{
            RequestV2 req = qianfan.chatCompletion()
                    .model(request.getModel())
                    .addMessage("system",request.getMessages().get(0).getContent())
                    .addMessage("user",request.getMessages().get(1).getContent())
                    .temperature(0.1).build();
            response = qianfan.chatCompletion(req);
//            String str = response.getChoices().get(0).getMessage().getContent();
            Message m = response.getChoices().get(0).getMessage();

            ChatResponse chatResponse = new ChatResponse();
            chatResponse.setModel(response.getModel());
            ChatRequest.Message msg = new ChatRequest.Message(m.getRole(),m.getContent());
            chatResponse.setMessage(msg);
            return  chatResponse;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Chat接口调用
     * @param model
     * @param systemPrompt    可以为空
     * @param userPrompt      不可为空
     * @return   字符串
     */
    public String chat(String model, String systemPrompt, String userPrompt){
        ResponseV2 response =  null;
        if(StringUtils.isEmpty(userPrompt)) throw new QianfanException("userPrompt 不能为空!");
        try{
            RequestV2 request = qianfan.chatCompletion()
                    .model(model)
                    .addMessage("system",systemPrompt)
                    .addMessage("user",userPrompt)
                    .temperature(0.1).build();
            response = qianfan.chatCompletion(request);
        }catch (Exception e){
            e.printStackTrace();
        }
        String str = response.getChoices().get(0).getMessage().getContent();
        return str;
    }

    public RerankResponse reran(RerankRequest request){
        String result = post("http://qianfan.baidubce.com/v2/rerankers", JSONObject.toJSONString(request));
        return JSONObject.parseObject(result,RerankResponse.class);
    }

    private String post(String url, String jsonRequest){
        try {
//            System.out.println(jsonRequest);
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost postRequest = new HttpPost(url);
            StringEntity entity = new StringEntity(jsonRequest, "UTF-8");
            postRequest.setHeader("Authorization","Bearer "+API_KEY);
            postRequest.setHeader("Content-Type","application/json");
            postRequest.setEntity(entity);
            CloseableHttpResponse resp = httpClient.execute(postRequest);
            HttpEntity e = resp.getEntity();
//            System.out.println(JSONObject.toJSONString(e));
//            System.out.println(resp.getStatusLine().getStatusCode());
            if(e!=null && resp.getStatusLine().getStatusCode() == 200){
                String content = EntityUtils.toString(e);
                return content;
            }
            return null;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {
        QianfanAgent qianfanClient = QianfanAgent.getInstance();
//        RerankRequest request = new RerankRequest(RerankRequest.model_rerank_bce_reranker_base,"",null,10);
//        request.setModel("bce-reranker-base");
//        request.setTop_n(2);
//        request.setQuery("盐酸曲美他嗪缓释片的适应症：作为添加药物，本品用于对一线抗心绞痛治疗控制不佳或无法耐受的稳定型心绞痛成年患者的对症治疗。");
//        List<String> docs = new ArrayList<>();
//        docs.add("盐酸曲美他嗪缓释片的适应症：作为添加药物，本品用于对一线抗心绞痛治疗控制不佳或无法耐受的稳定型心绞痛成年患者的对症治疗。");
//        docs.add("北京下雪");
//        request.setDocuments(docs);
//        RerankResponse response = qianfanClient.reran(request);
//        System.out.println(JSONObject.toJSONString(response));
        String system = "【系统指令】：\n" +
                "    你是一名临床医生，请参考【参考知识】并按照以下步骤分析【病历文书】内容，从中提取药物不良反应事件描述(可能有多个)，以及相关的药物实体和不良不良反应实体。\n" +
                "    判断是否存在药物相关不良反应事件：\n" +
                "    （1）判断标准：\n" +
                "    存在明确的时间关联性（用药后出现或加重）。\n" +
                "    存在药物暴露史（如化疗药、抗生素、激素、中药等）。\n" +
                "    临床表现符合药理或毒理作用。\n" +
                "    包含药物性诊断术语（如药物性肝炎、药疹等）。\n" +
                "    包含因果关系词（如“考虑为”、“不除外”、“与...有关”）。\n" +
                "    包含治疗措施变更（如停药、减量、对症处理）。\n" +
                "    （2）排除以下情况：\n" +
                "    仅提及药物但未出现不良反应。\n" +
                "    不是由药物导致的不良反应。\n" +
                "    预防性、警惕性、注意性用药描述。\n" +
                "    预防性、警惕性、注意性不良反应描述。\n" +
                "    停药后不良反应描述。\n" +
                "    既往史中已痊愈的药物不良反应事件。\n" +
                "    【参考知识】:\n" +
                " \t\"请示总住院医师，表示心衰症状不明显，仍考虑药物所致可能行大\"识别结果：{\"drugs\":[],\"reactions\":[\"心衰症状\"],\"sentence\":\"请示总住院医师，表示心衰症状不明显，仍考虑药物所致可能行大\"}\n" +
                "\t\"今日心内科会诊考虑患者气促与肺部疾患相关性大\"不是药物不良反应事件\n" +
                "\t\"结合胸片、心电图提示，考虑患者气促为心衰所致\"不是药物不良反应事件\n" +
                "\t\"心内科会诊考虑患者气促与胸水有关\"不是药物不良反应事件\n" +
                "\t\"患者诊断明确，突发气促不适加重\"不是药物不良反应事件\n" +
                "\t\"患者在家休息，第二天无诱因出现气促不适加重\"不是药物不良反应事件\n" +
                "\t\"患者气促考虑胸腔积液所致\"不是药物不良反应事件\n" +
                "\t\"患者无明显气促、咳嗽，可予停中心管道吸氧\"不是药物不良反应事件\n" +
                "\t\"患者经过抗感染、止咳祛痰、舒张支气管、扩血管等对症支持治疗后，症状明显改善，予停病重\"不是药物不良反应事件\n" +
                "\t\"患者目前双肺部满布湿性啰音，可平卧，经利尿强心治疗无明显改善，仍考虑肺部感染或出血可能大，因昨日考虑伊曲康唑过敏已停用\"不是药物不良反应事件\n" +
                "    【输出要求】\n" +
                "    输出为准确的JSON数组格式，无需任何解释和说明。\n" +
                "    输出结构参考：[{\"sentence\":\"文中药物不良反应事件描述\",\"drugs\":[\"药物实体1\",\"药物实体2\"],\"reactions\":[\"不良反应实体1\",\"不良反应实体1\"]}]";
        String user = "【病历文书】：2021-01-22 10:22                二级医师查房记录\n" +
                "           汤华主任医师查看病人，患者诉有阵发性胸闷、气促，睡眠、食欲较前好转。体查：P 89次/分 R 20次/分 Bp 116/68mmHg  SPO2 95%，神清，慢性重病容，半卧位，唇无发绀，颈静脉充盈，双肺叩诊呈过清音，双肺呼吸音低，可闻及湿性啰音。心界左下扩大，心率89次/分，律齐，心音低钝，未闻及杂音。腹软，无压痛及反跳痛，双下肢无凹陷性水肿。复查血气分析：剩余碱 -4.4mmol/L; 细胞外剩余碱 -7.4mmol/L; 实际碳酸氢盐 16.5; 标准碳酸氢盐 20.8mmol/L; 二氧化碳分压 22.4mmHg; 酸碱度 7.471; 二氧化碳总量 17.2mmol/L; 提示轻度呼吸性碱中毒。复查肾功能+电解质：白球比 0.95; 白蛋白 24.3g/L; 尿素 13.42mmol/L; 肌酐 157.4umol/L; 间接胆红素 2.2umol/L; 总蛋白 49.9g/L; 血清总钙 1.8mmol/L; 昨日胸水呈现血性积液，追问患者家属既往曾患有“结核性胸膜炎 胸腔积液”，故目前不排除“结核性胸膜炎”可能，建议进一步行结核相关检查（如血清TB-Spot及胸水XPert，属于自费项目），家属目前不同意行该项检查。汤华主任医师指示：患者昨日停用沙库巴曲缬沙坦后血压有所回升，夜间有阵发性胸闷气促发作，提示仍存在心衰，考虑到近2日已予以积极利尿、扩血管处理，患者水钠潴留明显减轻，目前心衰可考虑试用“左西孟旦”改善心衰，继续抗感染，抑酸护胃等对症支持治疗后，复查BNP、降钙素原，电解质、肾功能，以上遵执，注意监测生命体征。\n" +
                "医师签名:汤华/李靖";
        ChatRequest request = new ChatRequest(model_ernie35_8k, system, user);

        ChatResponse r = qianfanClient.chat(request);
        System.out.println(JSONObject.toJSONString(r, SerializerFeature.PrettyFormat));

    }


}
